package com.zw.pm.module.board.single;


import com.zw.pm.config.socket.WebSocketServer;
import com.zw.pm.constant.Constant;
import com.zw.pm.gen.entity.*;
import com.zw.pm.gen.mapper.DocMapper;
import com.zw.pm.gen.mapper.MessageMapper;
import com.zw.pm.gen.mapper.ProjectMapper;
import com.zw.pm.gen.mapper.TaskMapper;
import com.zw.pm.module.integrate.interactive.MessageDao;
import com.zw.pm.module.integrate.interactive.MessageModel;
import com.zw.pm.module.project.build.DocDao;
import com.zw.pm.module.system.user.UserDao;
import com.zw.pm.util.FileUtils;
import com.zw.pm.util.ShiroUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;

import static com.zw.pm.constant.Constant.*;

/**
 * @Description: 项目 服务层
 *
 * @Author: China.sgl
 * @Date: 2019/9/16 09:11
 */
@Service
public class SingleService {

    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private MessageMapper messageMapper;
    @Autowired
    private MessageDao messageDao;
    @Autowired
    private TaskMapper taskMapper;
    @Autowired
    private TaskDao taskDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private DocDao docDao;
    @Autowired
    private DocMapper docMapper;

    @Value("${user.upload.path}")
    private String uploadPath;

    /**
     * 根据 id 查询
     *
     * @param id id
     * @return Project
     */
    public Project getProjectById(Integer id) {
        return projectMapper.selectByPrimaryKey(id);
    }

    /**
     * 根据项目ID 查询互动消息
     *
     * @param id 项目ID
     * @return list
     */
    public List<MessageModel> findMessagesByProjectId(Integer id) {
        return messageDao.findByProjectId(id);
    }

    /**
     * 根据项目ID查询 模板 任务
     *
     * @param id 项目ID
     * @return TaskModel
     */
    public TaskModel findTaskByProjectIdAndTaskTempId(Integer id, Integer taskTempId) {
        return taskDao.findTaskByProjectIdAndTaskTempId(id, taskTempId);
    }

    /**
     * 根据项目ID查询 生产厂 任务
     *
     * @param id 项目ID
     * @return list
     */
    public List<TaskModel> findFactoryTaskByProjectId(Integer id) {
        return taskDao.findFactoryTaskByProjectId(id);
    }

    /**
     * 修改项目
     *
     * @param project 项目
     * @return 影响行数
     */
    public int updateProject(Project project) {
        return projectMapper.updateByPrimaryKeySelective(project);
    }

    /**
     * 查询所有用户
     *
     * @return list
     */
    public List<User> findUsers() {
        User user = new User();
        user.setStatus(STATUS_NORMAL);
        return userDao.findAll(user);
    }

    /**
     * 发送消息
     *
     * @param message 消息
     */
    public void sendMessage(Message message) {

        // 获取@用户名集合
        List<String> users = new ArrayList<>();
        Matcher matcher = Constant.USER_PATTERN.matcher(message.getContent());
        while (matcher.find()) {
            users.add(matcher.group(1));
        }

        message.setType(MESSAGE_TYPE_INTERACTIVE);
        message.setStatus(STATUS_NORMAL);
        message.setCreateTime(new Date());
        message.setSendUserId(ShiroUtils.getUserId());
        message.setUsers(StringUtils.join(users.toArray(), ","));

        if (users.size() == 0) {
            List<User> userList = userDao.findByReceiver();
            for (User user : userList) {
                message.setReceiverUserId(user.getId());
                messageMapper.insert(message);
            }
        } else {
            for (String s : users) {
                User u = userDao.getByName(s);
                message.setReceiverUserId(u.getId());
                messageMapper.insert(message);
            }
        }

        // 互动消息
        WebSocketServer.sendInfo("INTERACTIVE");
    }


    /**
     * 根据ID查任务
     *
     * @param id id
     * @return task
     */
    public TaskModel getTaskById(Integer id) {
        return taskDao.getById(id);
    }

    /**
     * 修改任务
     * 如果任务为“工艺”任务，同步数据到生产厂
     *
     * @param task task
     * @return 影响行数
     */
    public int editTask(Task task) {
        int row = taskDao.updateById(task);
        Task t = taskMapper.selectByPrimaryKey(task.getId());
        handlerProcessTask(t);
        handleProjectStatus(t.getProjectId());
        return row;
    }

    /**
     * 处理工艺任务
     * 如果编辑的工艺任务， 需要将数量和重量带入相应生产厂任务中
     *
     * @param task task
     */
    private void handlerProcessTask(Task task) {
        if (task.getTaskTempId() != null && task.getTaskTempId() == Constant.THEFIRST_PROCESS_TASK_TEMP_ID) {
            taskDao.updateOtherProduceTaskNumByProject(task);
            taskDao.updateOtherProduceTaskWeightByProject(task);
        } else if (task.getTaskTempId() != null && task.getTaskTempId() == Constant.THESECOND_PROCESS_TASK_TEMP_ID) {
            taskDao.updateFiveProduceTaskNumByProject(task);
            taskDao.updateFiveProduceTaskWeightByProject(task);
        }
    }

    /**
     * 修改任务状态
     *   未开始状态，清空“开始”和“完成”时间， 清空“原因”
     *   执行中状态，清空“完成”时间，设置“开始”时间，清空“原因”
     *   已完成状态，设置“原因”， 设置“完成”时间
     * 处理项目状态
     *
     * @param task task
     * @return 影响行数
     */
    public int taskStatus(Task task) {
        Task t = taskMapper.selectByPrimaryKey(task.getId());
        t.setStatus(task.getStatus());
        switch (t.getStatus()) {
            case TASK_STATUS_NOT_BEGIN:
                t.setStartTime(null);
                t.setEndTime(null);
                t.setReason("");
                break;
            case TASK_STATUS_EXECATE:
                t.setStartTime(new Date());
                t.setEndTime(null);
                t.setReason("");
                break;
            case TASK_STATUS_COMPLETED:
                t.setEndTime(new Date());
                t.setReason(task.getReason());
                break;
            default:
                t.setStartTime(null);
                t.setEndTime(null);
        }
        int row = taskMapper.updateByPrimaryKey(t);
        handleProjectStatus(t.getProjectId());
        return row;
    }

    /**
     * 处理项目状态
     *
     * @param projectId 项目ID
     */
    public void handleProjectStatus(Integer projectId) {
        Project project = projectMapper.selectByPrimaryKey(projectId);
        float process = taskDao.findProcessStatusByProjectId(projectId);
        if (process == TASK_STATUS_NOT_BEGIN) {
            project.setProcessStatus(TASK_STATUS_NOT_BEGIN);
            project.setProcessCompleteTime(null);
        } else if (process == TASK_STATUS_COMPLETED) {
            project.setProcessStatus(TASK_STATUS_COMPLETED);
            if (project.getProcessCompleteTime() == null) {
                project.setProcessCompleteTime(new Date());
            }
        } else {
            project.setProcessStatus(TASK_STATUS_EXECATE);
            project.setProcessCompleteTime(null);
        }
        float produce = taskDao.findProduceStatusByProjectId(projectId);
        if (produce == TASK_STATUS_NOT_BEGIN) {
            project.setProduceStatus(TASK_STATUS_NOT_BEGIN);
            project.setProduceCompleteTime(null);
        } else if (produce == TASK_STATUS_COMPLETED) {
            project.setProduceStatus(TASK_STATUS_COMPLETED);
            if (project.getProduceCompleteTime() == null) {
                project.setProduceCompleteTime(new Date());
            }
        } else {
            project.setProduceStatus(TASK_STATUS_EXECATE);
            project.setProduceCompleteTime(null);
        }
        float all = taskDao.findAllStatusByProjectId(projectId);
        if (all == TASK_STATUS_COMPLETED) {
            project.setStatus(TASK_STATUS_COMPLETED);
            if (project.getCompleteTime() == null) {
                project.setCompleteTime(new Date());
            }
        } else {
            project.setStatus(TASK_STATUS_EXECATE);
            project.setCompleteTime(null);
        }
        projectMapper.updateByPrimaryKey(project);
    }

    /**
     * 撤消任务进度
     *
     * @param task task
     * @return status
     */
    public int taskCancel(Task task) {
        Task t = taskMapper.selectByPrimaryKey(task.getId());
        t.setStatus(t.getStatus() - 1);
        taskStatus(t);
        return t.getStatus();
    }

    /**
     * 根据任务ID查询文件
     *
     * @param id id
     * @return list
     */
    public List<Doc> findDocByTaskId(Integer id) {
        return docDao.findByTaskId(id);
    }

    /**
     * 上传文件
     *
     * @param doc doc
     * @param file 文件
     * @return 行数
     */
    public int upload(Doc doc, MultipartFile[] file) {
        return saveFile(doc, file);
    }

    /**
     * 保存文件
     *
     * @param doc doc
     * @param file file
     * @return 行数
     */
    private int saveFile(Doc doc, MultipartFile[] file) {
        int row = 0;
        if (null != file && file.length > 0) {
            for (MultipartFile f : file) {
                String path = uploadPath + "project/" + doc.getProjectId() + "/" + doc.getTaskId() + "/";
                String fileName = FileUtils.upload(f, path);
                if (com.zw.pm.util.StringUtils.isNotNull(fileName)) {
                    String url = "/files/project/" + doc.getProjectId() + "/" + doc.getTaskId() + "/" + fileName;
                    if (docDao.countByUrl(url) > 0) {
                        continue;
                    }
                    Doc document = new Doc();
                    document.setName(fileName);
                    document.setUrl(url);
                    document.setPath(path + fileName);
                    document.setProjectId(doc.getProjectId());
                    document.setTaskId(doc.getTaskId());
                    document.setStatus(STATUS_NORMAL);
                    document.setUploadTime(new Date());
                    document.setUserId(ShiroUtils.getLoginName());
                    row += docMapper.insert(document);
                }
            }
        }
        return row;
    }

    /**
     * 文件下载
     *
     * @param response response
     * @param id id
     */
    public void download(HttpServletResponse response, Integer[] id) {
        if (id.length == 1) {
            Doc doc = docMapper.selectByPrimaryKey(id[0]);
            FileUtils.downloadFile(doc.getPath(), response);
        } else {
            List<String> fileNames = new ArrayList<>();
            Doc doc;
            for (Integer integer : id) {
                doc = docMapper.selectByPrimaryKey(integer);
                fileNames.add(doc.getPath());
            }
            FileUtils.zipFileAll(fileNames, response);
        }
    }

    /**
     * 删除文件
     *
     * @param id 文件ID数组
     * @return 影响行数
     */
    public int delFile(Integer[] id) {
        int row = 0;
        for (Integer i : id) {
            Doc doc = docMapper.selectByPrimaryKey(i);
            File file = new File(doc.getPath());
            if (file.exists()) {
                file.delete();
            }
            row += docMapper.deleteByPrimaryKey(i);
        }
        return row;
    }

    /**
     * 设置消息为已读
     *
     * @param msgId messageId
     */
    public void handlerMessage(Integer msgId) {
        messageDao.updateStatusById(msgId);
    }
}
